package com.zsx.shopping.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsx.shopping.common.api.search.dto.SkuEsDto;
import com.zsx.shopping.common.enums.CodeMsg;
import com.zsx.shopping.common.api.R;
import com.zsx.shopping.common.api.search.feign.SearchFeignService;
import com.zsx.shopping.common.api.ware.feign.WareFeignService;
import com.zsx.shopping.common.api.ware.vo.SkuStockVO;
import com.zsx.shopping.common.exception.ShoppingException;
import com.zsx.shopping.product.converter.SkuAttrConverter;
import com.zsx.shopping.product.converter.SpuAttrConverter;
import com.zsx.shopping.product.entity.*;
import com.zsx.shopping.product.mapper.*;
import com.zsx.shopping.product.service.SpuService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 *
 */
@Service
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu>
    implements SpuService{

    @Resource
    private SpuMapper spuMapper;

    @Resource
    private SkuMapper skuMapper;

    @Resource
    private BrandMapper brandMapper;

    @Resource
    private SpuAttrMapper spuAttrMapper;

    @Resource
    private SkuAttrMapper skuAttrMapper;

    @Resource
    private WareFeignService wareFeignService;

    @Resource
    private SearchFeignService searchFeignService;

    @Resource
    private SpuAttrConverter spuAttrConverter;

    @Resource
    private SkuAttrConverter skuAttrConverter;

    @Override
    public void upload(Long spuId) {
        Spu spu = spuMapper.selectById(spuId);
        List<Sku> skus = skuMapper.selectList(new LambdaQueryWrapper<Sku>().eq(Sku::getSpuId, spuId));
        List<Long> skuIds = skus.stream().map(Sku::getId).collect(Collectors.toList());
        Map<Long, SkuStockVO> skuStockVOMap = wareFeignService.getSkuStock(skuIds).getData();
        Brand brand = brandMapper.selectById(spu.getBrandId());
        Map<Long, List<SkuEsDto.Attr>> map = this.getEnableSearchAttrs(spuId);

        ArrayList<SkuEsDto> skuEsDtos = new ArrayList<>(skus.size());
        for(Sku sku : skus) {
            SkuEsDto skuEsDTO = new SkuEsDto();
            skuEsDTO.setSkuId(sku.getId());
            skuEsDTO.setSkuName(sku.getName());
            skuEsDTO.setCategoryId(spu.getCatId());
            skuEsDTO.setSkuDefaultImage(sku.getDefaultImage());
            skuEsDTO.setBrandName(brand.getName());
            skuEsDTO.setBrandImage(brand.getImage());
            skuEsDTO.setSkuPrice(sku.getPrice());
            skuEsDTO.setHasStock(skuStockVOMap.get(sku.getId()).getStock() > 0);
            skuEsDTO.setSales(skuStockVOMap.get(sku.getId()).getSales());
            skuEsDTO.setBrandId(brand.getId());
            skuEsDTO.setAttrs(map.get(sku.getId()));
            skuEsDtos.add(skuEsDTO);
        }

        R<Void> r = searchFeignService.saveProduct(skuEsDtos);
        if (CodeMsg.SUCCESS.getCode().equals(r.getCode())) {
            spu.setPublishState(true);
            spuMapper.updateById(spu);
        } else {
            throw new ShoppingException(r.getCode(), r.getMsg());
        }
    }

    private Map<Long, List<SkuEsDto.Attr>> getEnableSearchAttrs(Long spuId) {
        List<SpuAttr> spuAttrs = spuAttrMapper.selectList(new LambdaQueryWrapper<SpuAttr>().eq(SpuAttr::getSpuId, spuId));
        List<SkuAttr> skuAttrs = skuAttrMapper.getAllEnableSearchSkuAttrsBySpuId(spuId);

        HashMap<Long, List<SkuEsDto.Attr>> map = new HashMap<>();
        for (SkuAttr skuAttr : skuAttrs) {
            if (!map.containsKey(skuAttr.getSkuId())) {
                map.put(skuAttr.getSkuId(), new LinkedList<>());
            }
            SkuEsDto.Attr skuEsDTOAttr = skuAttrConverter.toSkuEsDTOAttr(skuAttr);
            map.get(skuAttr.getSkuId()).add(skuEsDTOAttr);
        }
        List<SkuEsDto.Attr> skuEsDTOAttrs = spuAttrConverter.toSkuEsDTOAttrs(spuAttrs);
        for (List<SkuEsDto.Attr> attrs : map.values()) {
            attrs.addAll(skuEsDTOAttrs);
        }

        return map;
    }
}




